<?php 
/**
 * This file is part of DomAr.
 * 
 * DomAr is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * DomAr is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with DomAr.  If not, see <http://www.gnu.org/licenses/>.
 * 
 * @link http://inditel.ee/
 * @copyright 2007-2009 Inditel Meedia OÜ
 * @author Oliver Leisalu <oliver@inditel.ee>
 */

/**
* @package DomAr
* @subpackage Relation
*/
class DomArOneToMany extends DomArOneToOne {
	
	/**
	* @param DomArObject $object
	* @param Int|DomArObject $newPropertyValue
	*/
	public function beforeSet( DomArObject $object, &$oldPropertyValue, &$newPropertyValue ) {
		
		if( is_object($oldPropertyValue) ) {
			
			if( $this->actAsParent === false && $this->composition === false && $object->getId() > 0 && $oldPropertyValue->id > 0)
				DomSql::query('UPDATE '.$object->getTableName().' SET '.$this->name.' = NULL WHERE id='.$object->getId().' LIMIT 1');

			$this->beforeDelete( $object, $oldPropertyValue );
			
		}
		
	}
	/**
	* @param DomArObject $object
	* @param Int|DomArObject $propertyValue
	*/	
	public function afterSet( DomArObject $object, &$propertyValue ) {	
		if( is_object($propertyValue) && $this->inverse !== NULL ) {
			$propertyValue->getProperty($this->inverse)->invokeListener('beforeadd', $propertyValue, $object );
			$propertyValue->{$this->inverse}->addNewObject( $object );
			$propertyValue->getProperty($this->inverse)->invokeListener('afteradd', $propertyValue, $object );
		}
	}
	
	/**
	* @param DomArObject $object
	* @param Int $propertyValue
	* @return DomArObject
	*/
	public function load( DomArObject $object, &$propertyValue ) {
		if( $propertyValue == 0 )
			return NULL;
		return DomAr::load( $propertyValue, $this->childClassName);	
	}

	public function beforeInsert( DomArSession $session, DomArObject $object, &$propertyValue ) {
		$this->beforeUpdate( $session, $object, $propertyValue );
	}
	
	public function insert( DomArObject $object, &$propertyValue, DomArValueSet $set  ) {        
		if( $propertyValue->id > 0 ) {
			$set->set( $this->name, (int)$propertyValue->id );
		} else {
			$object->setChanged( $this->name, true );
			$set->set( $this->name, 'NULL' );
		}
	}

	public function beforeUpdate( DomArSession $session, DomArObject $object, &$propertyValue ) {
		if( !$propertyValue ) return;
		$session->add( $propertyValue );
		//$session->addRelation( $object, $propertyValue );
	}
	
	public function update( DomArObject $object, &$propertyValue, DomArValueSet $set ) {
		$set->set( $this->name, ($propertyValue->id > 0 ? (int)$propertyValue->id : 'NULL') );
	}

	public function validate( DomArObject $object, &$value, array &$customParams = array(), $validateParentForChild = true ) {
		
		$parentValidate = ($value == 0 or $value instanceof $this->childClassName && call_user_func(array(get_class($value), 'getDbTable')) == call_user_func(array($this->childClassName, 'getDbTable'))) ? 0 : 1;
		
		if( $parentValidate !== 0 )
			return $parentValidate;
		
		if( is_object($value) && $this->inverse && $validateParentForChild === true) {
			$property = $value->getProperty( $this->inverse );
			return $property->set_validate( $value, $object, $customParams, false );
		}
		
		return 0;
	}
	
	
	
	/**
	* @param DomArTable $table Parent table.
	*/
	public function alterTable( DomArTable $table ) {
		$table->changeColumn( $this->name, 'bigint', true );
		$table->changeIndex( $table->tableName.'_'.$this->name, array($this->name), 'index' );
			
		$childTable = call_user_func( array($this->childClassName, 'getTable') )->update();
	}
	
	
	/**
	* Removes parent from child if inversed.
	* @param DomArObject $object
	* @param DomArObject $propertyValue
	*/
	public function beforeDelete( DomArObject $object, &$propertyValueRef ) {
		
		$propertyValue = $propertyValueRef;
		
		$object->forceSet( $this->name, NULL);
		
		if( is_object($propertyValue) === true ) {
		
			if( $this->inverse !== NULL ) {
				$propertyValue->getProperty($this->inverse)->invokeListener('beforeremove', $propertyValue, $object );
				$propertyValue->{$this->inverse}->unload( $object );
				$propertyValue->getProperty($this->inverse)->invokeListener('afterremove', $propertyValue, $object );
			}
			
			if( $propertyValue->id > 0 ) {
				
				if( $this->composition === true ) {
					$propertyValue->delete();
				} else if( $this->inverse !== NULL && $object->id > 0) {
					$propertyValue->save();
				}
				
				if( $this->actAsParent === true or $this->composition === true && $this->inverse === NULL && $object->id > 0)
					DomSql::query('UPDATE '.$object->getTableName().' SET '.$this->name.' = NULL WHERE id = '.$object->id.' LIMIT 1');
			}
		}
	}

}
?>